/**
* \file DGVLatticeVTK.h
*
* \brief This file defines a class for displaying lattices using VTK.
* \author Shekhar S. Chandra, 2008
*
* This file is part of DGV Library.
*
* DGV is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DGV is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DGV.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DGVLATTICEVTK_H
#define DGVLATTICEVTK_H

#include "QVTKWidget.h"

#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkAxesActor.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"

#include "DGVAliases.h"

typedef double latticeType;

/*!
    \class DGVLatticeVTK
    \brief This class represents lattices in the form of the Fundamental Lattice in Number Theory. EXPERIMENTAL
    \author Shekhar S. Chandra, 2008
*/
class DGV_VTK_EXPORT DGVLatticeVTK : public QVTKWidget
{
    Q_OBJECT

public:
    DGVLatticeVTK(QWidget *parent = 0);
    virtual ~DGVLatticeVTK();

    /*!
        \fn DGVLatticeVTK::setName(QString filename)
        \brief Set the name of the lattice.
    */
    void setName(QString filename);
    void setDimensions(int dimensions);
    void setDefaultSize(int value);
    inline void setLatticeParameters(Array<latticeType,1> &values)
    {   latticeParameters = values;     }
    inline void setLatticeSize(int x, int y)
    {   latticeSize = x, y;    }
    inline void setLatticeSize(Array<int,1> &sizes)
    {   latticeSize = sizes;    }
    inline void setLatticePointSize(latticeType value)
    {   defaultRadius = value;  }
    inline void setLatticeUnit(latticeType value)
    {   unit = value;   }
    void setBackgroundColour(double red, double green, double blue);
    void setLatticeColour(double red, double green, double blue);
    void setLatticePointColour(int x, int y, double red, double green, double blue);

    inline int getDimension()
    {   return dimension;   }
    inline int getDefaultSize()
    {   return defaultSize; }
    inline latticeType getLatticeUnit()
    {   return unit;    }
    inline Array<latticeType,1>& getLatticeParameters()
    {   return latticeParameters;   }
    inline Array<int,1>& getLatticeSize()
    {   return latticeSize; }

    void addActorToLattice(vtkActor *actorToAdd);
    void generateLattice();
    void viewAsRightHanded();
    void viewAsMatrix();
    void enableAxes();
    void disableAxes();

    /*!
        \fn DGVLatticeVTK::strippedName()
        \brief Returns the stripped (path removed) name of the lattice.
    */
    QString strippedName();
    /*!
        \fn DGVLatticeVTK::strippedNamePrefix()
        \brief Returns the stripped (path removed) name of the lattice with "Lattice" prefix.
    */
    QString strippedNamePrefix();

protected:
    Array<latticeType,1> latticeParameters;
    Array<int,1> latticeSize;
    latticeType unit;
    int dimension;
    int defaultSize;
    latticeType defaultRadius;
    bool generatedBefore;
    bool rightHanded;
    bool axesEnabledBefore;
    QString name; //!< Name of the plot

    vtkSphereSource *sphere; //!< Sphere form of a lattice point
    vtkPolyDataMapper *mapper; //!< Map of the surface of a sphere
    Array<vtkActor*,1> latticePoints; //!< Actors for the lattice points. Represents the lattice points.
    vtkAxesActor *axes; //!< Axes for the lattice
    vtkProperty *property; //!< Common Lattice Point Properties
    vtkRenderer *renderer; //!< Renderer of the lattice
    vtkRenderWindow *renderWin; //!< Window that controls the renderer
};

#endif // DGVLATTICEVTK_H
